<!--
 * hi-a-component - 环形进度条
 *
 * @author 济南晨霜信息技术有限公司
 * @mobile 18560000860 / 18754137913
 -->
<template>
    <view class="hi-circle-progress" :class="_classes" :style="_styles">
        <view class="hi-circle-progress__circle" :style="_circleStyles"></view>
        <view class="hi-circle-progress__content">
            <slot>
                <view class="hi-circle-progress__status" v-if="showStatus">
                    <!-- 进行中 -->
                    <view class="hi-circle-progress__status__module hi-circle-progress__status__module--on" v-if="status === 'on'">
                        <text class="hi-circle-progress__status__text">{{ _text }}</text>
                    </view>

                    <!-- 成功 -->
                    <view class="hi-circle-progress__status__module hi-circle-progress__status__module--success" v-else-if="status === 'success'">
                        <hi-icon class="hi-circle-progress__status__icon hi-circle-progress__status__icon--success" :name="successIcon"></hi-icon>
                    </view>

                    <!-- 失败 -->
                    <view class="hi-circle-progress__status__module hi-circle-progress__status__module--success" v-else-if="status === 'fail'">
                        <hi-icon class="hi-circle-progress__status__icon hi-circle-progress__status__icon--fail" :name="failIcon"></hi-icon>
                    </view>
                </view>
            </slot>
        </view>
    </view>
</template>

<!-- 由于 HbuilderX 不支持 defineOptions() 写法，故只能在此处进行配置 -->
<script>
    export default { options: uni?.$hi?.config?.componentsOptions || {} };
</script>

<script setup>
    import { ref, computed, watch } from "vue";
    import props from "./props.js";
    import { isString, isArray, sleep, floatFormat } from "../../functions";

    // props
    const _props = defineProps(props);

    // emits
    const _emits = defineEmits([""]);

    // classes
    const _classes = computed(() => {
        const classes = [];

        // 主题
        if (_props.theme) classes.push(`--hi-circle-progress-theme --hi-circle-progress-theme--${_props.theme}`);

        return classes;
    });

    // styles
    const _styles = computed(() => {
        const styles = [];

        // 主题
        if (_props.theme) styles.push(`--hi-circle-progress-active-color: var(--hi-theme-${_props.theme});`);

        // 大小
        if (_props.size) styles.push(`--hi-circle-progress-size: ${_props.size};`);

        // 进度条宽度
        if (_props.width) styles.push(`--hi-circle-progress-width: ${_props.width};`);

        // 未激活颜色
        if (_props.inactiveColor) styles.push(`--hi-circle-progress-inactive-color: ${_props.inactiveColor};`);

        // 进度条中间圆的颜色
        if (_props.bg) styles.push(`--hi-circle-progress-background: ${_props.bg};`);

        // 状态内容颜色
        if (_props.statusColor) styles.push(`--hi-circle-progress-status-color: ${_props.statusColor};`);

        // 状态内容大小
        if (_props.statusFontSize) styles.push(`--hi-circle-progress-status-font-size: ${_props.statusFontSize};`);

        // 成功图标颜色
        if (_props.successIconColor) styles.push(`--hi-circle-progress-status-success-icon-color: ${_props.successIconColor};`);

        // 成功图标大小
        if (_props.successIconSize) styles.push(`--hi-circle-progress-status-success-icon-font-size: ${_props.successIconSize};`);

        // 失败图标颜色
        if (_props.failIconColor) styles.push(`--hi-circle-progress-status-fail-icon-color: ${_props.failIconColor};`);

        // 失败图标大小
        if (_props.failIconSize) styles.push(`--hi-circle-progress-status-fail-icon-font-size: ${_props.failIconSize};`);

        return styles;
    });

    // 进度条样式
    const _circleStyles = computed(() => {
        const styles = [];

        // 进度条颜色
        let colors = [];

        // 通过 props 设置了颜色
        if (_props.color) {
            if (isString(_props.color)) colors.push(_props.color);
            if (isArray(_props.color)) {
                _props.color.forEach((item) => colors.push(item));
            }
        }

        // 未通过 props 设置颜色，使用默认颜色
        else {
            colors.push("var(--hi-circle-progress-active-color, var(--hi-theme-primary))");
        }

        // 将当前进度值设置到最后一个颜色上
        let lastIndex = colors.length - 1;
        let lastColor = colors[lastIndex];
        lastColor = `${lastColor} ${_percent.value}%`;
        colors[lastIndex] = lastColor;

        // 加上未激活进度条的颜色
        if (_props.inactiveColor) {
            colors.push(`${_props.inactiveColor} ${_percent.value}%`);
            colors.push(`${_props.inactiveColor} 100%`);
        } else {
            colors.push(`var(--hi-circle-progress-inactive-color, var(--hi-background-default)) ${_percent.value}%`);
            colors.push(`var(--hi-circle-progress-inactive-color, var(--hi-background-default)) 100%`);
        }

        // 设置到背景上
        styles.push(`background: conic-gradient(${colors.join(",")});`);

        return styles;
    });

    // 进度
    const _percent = ref(_props.percent);

    // 监听进度，使用定时器实现进度过渡动效
    watch(
        () => _props.percent,
        async (newVal, oldVal) => {
            if (newVal == oldVal) {
                _percent.value = newVal;
            } else {
                // 步近式更新进度
                updatePercentByStep();
            }
        },
        {
            immediate: true
        }
    );

    // 步近式更新进度
    async function updatePercentByStep() {
        if (_percent.value < _props.percent) {
            if (_percent.value + _props.step > _props.percent) {
                _percent.value = _props.percent;
                return;
            } else {
                _percent.value = _percent.value + _props.step;
                await sleep(_props.interval);
                updatePercentByStep();
            }
        } else {
            if (_percent.value - _props.step < _props.percent) {
                _percent.value = _props.percent;
                return;
            } else {
                _percent.value = _percent.value - _props.step;
                await sleep(_props.interval);
                updatePercentByStep();
            }
        }
    }

    // 进度文字
    const _text = computed(() => {
        // 自定义了格，将格式化字符串中的 {percent} 替换成对应的值
        if (_props.format) {
            return _props.format.replace("{percent}", floatFormat(_percent.value, 2, false));
        }

        // 默认格式
        return floatFormat(_percent.value, 2, false) + "%";
    });
</script>

<style lang="scss" scoped>
    .hi-circle-progress {
        display: inline-block;
        width: var(--hi-circle-progress-size, 90px);
        height: var(--hi-circle-progress-size, 90px);
        position: relative;
        border-radius: 50%;
        background: var(--hi-circle-progress-background);

        &__circle {
            width: 100%;
            height: 100%;
            border-radius: 50%;
            mask: radial-gradient(
                transparent calc(var(--hi-circle-progress-size, 90px) / 2 - var(--hi-circle-progress-width, 10px)),
                #000000 calc(var(--hi-circle-progress-size, 90px) / 2 - var(--hi-circle-progress-width, 10px))
            );
        }

        &__content {
            position: absolute;
            left: var(--hi-circle-progress-width, 10px);
            top: var(--hi-circle-progress-width, 10px);
            right: var(--hi-circle-progress-width, 10px);
            bottom: var(--hi-circle-progress-width, 10px);
            z-index: 8;
            display: flex;
            justify-content: var(--hi-circle-progress-content-justify-content, center);
            flex-direction: var(--hi-circle-progress-content-flex-direction, column);
            align-items: var(--hi-circle-progress-content-align-items, center);
            text-align: var(--hi-circle-progress-content-text-align, center);
            border-radius: 50%;
        }

        &__status {
            font-size: var(--hi-circle-progress-status-font-size, 1.15em);
            color: var(--hi-circle-progress-status-color);

            &__icon {
                --hi-icon-font-size: var(--hi-circle-progress-status-icon-font-size, 1.15em);
                --hi-icon-color: var(--hi-circle-progress-status-icon-color);

                &--success {
                    --hi-icon-font-size: var(--hi-circle-progress-status-success-icon-font-size, var(--hi-circle-progress-status-icon-font-size, 1.15em));
                    --hi-icon-color: var(
                        --hi-circle-progress-status-success-icon-color,
                        var(--hi-circle-progress-status-icon-color, var(--hi-circle-progress-active-color, var(--hi-theme-primary)))
                    );
                }

                &--fail {
                    --hi-icon-font-size: var(--hi-circle-progress-status-fail-icon-font-size, var(--hi-circle-progress-status-icon-font-size, 1.15em));
                    --hi-icon-color: var(
                        --hi-circle-progress-status-fail-icon-color,
                        var(--hi-circle-progress-status-icon-color, var(--hi-circle-progress-active-color, var(--hi-theme-error)))
                    );
                }
            }
        }
    }
</style>
